package com.graduation_design.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.graduation_design.common.exception.HubException;
import com.graduation_design.entity.AppOrder;
import com.graduation_design.entity.AppRefund;
import com.graduation_design.entity.AppUser;
import com.graduation_design.service.*;
import com.graduation_design.mapper.AppRefundMapper;
import com.graduation_design.utils.ShiroUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 从南
* @description 针对表【app_refund】的数据库操作Service实现
* @createDate 2024-02-16 18:15:58
*/
@Service
public class AppRefundServiceImpl extends ServiceImpl<AppRefundMapper, AppRefund>
    implements AppRefundService{

    @Resource
    AppOrderService appOrderService;

    @Resource
    AppOrderItemService appOrderItemService;

    @Resource
    AppUserService appUserService;

    @Resource
    AppRefundMapper appRefundMapper;

    @Resource
    AppPayService appPayService;

    /**
     * 退款界面的基础数据
     */
    @Override
    public Object getOrderData(Long orderId) {

        AppOrder appOrder = appOrderService.getOwnById(orderId);
        appOrder.setOrderItems(appOrderItemService.listByOrderId(orderId));
        return MapUtil.builder()
                .put("reasons", Arrays.asList("多拍/拍错/不想要了", "不喜欢/效果不好","少件/发错货/未收到货", "商品与描述不符", "商品质量/故障"))
                .put("methods", Arrays.asList("自行寄回", "上门取货", "仅退款"))
                .put("order", appOrder)
                .build();
    }

    /**
     * 用户选择退款理由和方式之后发起退款
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object apply(AppRefund appRefund) {
        AppOrder appOrder = appOrderService.getOwnById(appRefund.getOrderId());

        // 判断是否能申请退款
        Assert.isTrue(Arrays.asList(1, 2, 3).contains(appOrder.getOrderStatus()), "该订单状态不支持退款");

        // 根据订单状态区分处理方式、待发货的立即退款、待收货已完成的进入后台处理
        if (appOrder.getOrderStatus() == 1) {
            // 未发货直接退款
            appRefund.setRefundStatus(2);
            appOrder.setOrderStatus(6);

            // TODO 支付宝退款操作

        } else {
            // 已发货退款
            appRefund.setRefundStatus(0);
            appOrder.setOrderStatus(5);
        }

        // 更新状态
        appRefund.setOrderId(appOrder.getId());
        appRefund.setOrderSn(appOrder.getSn());
        appRefund.setUserId(appUserService.getCurrentUserId());

        appRefund.setSn(generateRefundSn());
        appRefund.setRefundAmount(appOrder.getTotalAmount());
        appRefund.setCreated(LocalDateTime.now());
        this.save(appRefund);

        appOrder.setRefundTime(LocalDateTime.now());
        appOrder.setUpdated(LocalDateTime.now());
        appOrderService.updateById(appOrder);
        return null;
    }

    @Override
    public Object pageAdmin(Page page, AppRefund appRefund) {
         return appRefundMapper.pageWithUsername(page, new QueryWrapper<AppRefund>()
                .eq(appRefund.getSn() != null, "sn", appRefund.getSn())
                .eq(appRefund.getOrderSn() != null, "order_sn", appRefund.getOrderSn())
                .eq(appRefund.getRefundStatus() != null, "return_status", appRefund.getRefundStatus())
                .orderByDesc("created")
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditAdmin(AppRefund appRefund) {
        Assert.notNull(appRefund.getRefundStatus(), "状态异常");


        AppRefund refund = this.getById(appRefund.getId());
        AppOrder appOrder = appOrderService.getById(refund.getOrderId());
        // 1表示退货中，3表示拒绝退货
        if (appRefund.getRefundStatus() == 1 || appRefund.getRefundStatus() == 3) {
            // 确认退货、拒绝退货
            Assert.isTrue(refund.getRefundStatus() == 0, "状态异常");
            Assert.isTrue(appRefund.getRefundAmount() != null && StrUtil.isNotBlank(appRefund.getOperateRemark()), "请输入处理金额和内容");
            Assert.isTrue(appRefund.getRefundAmount().compareTo(appOrder.getTotalAmount()) <= 0, "退款金额不得大于订单金额");

            refund.setRefundAmount(appRefund.getRefundAmount());
            refund.setRefundStatus(appRefund.getRefundStatus());
            refund.setOperateRemark(appRefund.getOperateRemark());

            refund.setOperatorId(ShiroUtil.getProfile().getId());
            refund.setOperateTime(LocalDateTime.now());

            if (appRefund.getRefundStatus() == 3) {
                appOrder.setOrderStatus(7);
                appOrderService.updateById(appOrder);
            }

        } else if (appRefund.getRefundStatus() == 2) {
            // 2表示确认退货退款
            // 确认收货
            Assert.isTrue(refund.getRefundStatus() == 1, "状态异常");
            Assert.isTrue(StrUtil.isNotBlank(appRefund.getReceiptRemark()), "请输入收货备注");

            refund.setReceiptRemark(appRefund.getReceiptRemark() + " | " + DateUtil.now());
            refund.setRefundStatus(appRefund.getRefundStatus());

            // 退款成功
            appOrder.setOrderStatus(6);
            appOrder.setRefundTime(LocalDateTime.now());
            appOrderService.updateById(appOrder);

            // 支付宝退款
            appPayService.refund(appRefund.getId());
        }

        refund.setUpdated(LocalDateTime.now());
        this.updateById(refund);
    }

    private String generateRefundSn() {
        String dataStr = DateUtil.format(new Date(), "yyMMddHHmm");
        return "T" + dataStr + RandomUtil.randomNumbers(4);
    }
}




